import * as Cesium from 'cesium';
import OrbitCalculator from './OrbitCalculator.js';

/**
 * 自定义卫星实体类
 * 扩展原有SatelliteEntity功能，支持从六根数创建卫星轨道
 */
class CustomSatelliteEntity {
	/**
	 * 构造函数
	 * @param {Object} config - 配置参数
	 * @param {string} config.name - 卫星名称
	 * @param {Object} config.orbitElements - 轨道六根数
	 * @param {Object} config.options - 可选参数
	 */
	constructor(config) {
		this.name = config.name || 'Custom Satellite';
		this.orbitElements = config.orbitElements;
		this.options = config.options || {};

		// 创建轨道计算器
		this.orbitCalculator = new OrbitCalculator(this.orbitElements, this.options.epoch);

		// 轨道显示参数
		this.totalSeconds = this.options.totalSeconds || this.orbitCalculator.orbitalPeriod * 2; // 默认显示2个轨道周期
		this.stepSeconds = this.options.stepSeconds || 60; // 默认60秒步长

		// 轨道显示策略
		this.leadTime = this.options.leadTime || this.orbitCalculator.orbitalPeriod;
		this.trailTime = this.options.trailTime || this.orbitCalculator.orbitalPeriod;

		// 视觉样式
		this.color = this.options.color || Cesium.Color.fromRandom({ alpha: 0.8 });
		this.pointSize = this.options.pointSize || 8;
		this.pathWidth = this.options.pathWidth || 1.5;
		this.showLabel = this.options.showLabel !== false; // 默认显示标签
		this.showPath = this.options.showPath !== false; // 默认显示轨道

		// Cesium实体
		this.entity = null;
	}

	/**
	 * 创建位置属性
	 * @returns {Cesium.SampledPositionProperty} 位置属性
	 */
	_createPositionProperty() {
		const startTime = this.options.startTime || Date.now();
		const start = Cesium.JulianDate.fromDate(new Date(startTime));

		// 使用INERTIAL坐标系，让轨道在惯性空间中保持固定
		const positionProperty = new Cesium.SampledPositionProperty(Cesium.ReferenceFrame.INERTIAL);

		// 生成轨道轨迹点
		const trajectory = this.orbitCalculator.generateOrbitTrajectory(startTime, this.totalSeconds, this.stepSeconds);

		// 添加轨道点到位置属性
		trajectory.forEach((point, index) => {
			const cesiumTime = Cesium.JulianDate.addSeconds(start, index * this.stepSeconds, new Cesium.JulianDate());

			// 转换为Cesium坐标 (米)
			const position = new Cesium.Cartesian3(point.position.x * 1000, point.position.y * 1000, point.position.z * 1000);

			positionProperty.addSample(cesiumTime, position);
		});

		return positionProperty;
	}

	/**
	 * 创建卫星实体
	 * @returns {Object} Cesium实体对象
	 */
	createSatelliteEntity() {
		const startTime = this.options.startTime || Date.now();
		const start = Cesium.JulianDate.fromDate(new Date(startTime));
		const stop = Cesium.JulianDate.addSeconds(start, this.totalSeconds, new Cesium.JulianDate());

		this.entity = {
			name: this.name,
			description: this._createDescription(),
			availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({ start: start, stop: stop })]),
			position: this._createPositionProperty(),

			// 卫星点
			point: {
				pixelSize: this.pointSize,
				color: this.color,
				outlineColor: Cesium.Color.BLUE,
				outlineWidth: 1,
				heightReference: Cesium.HeightReference.NONE
			},

			// 轨道路径
			path: new Cesium.PathGraphics({
				width: this.pathWidth,
				show: this.showPath,
				leadTime: this.leadTime,
				trailTime: this.trailTime,
				material: this.color,
				resolution: 120 // 路径分辨率
			}),

			// 标签
			label: this.showLabel
				? {
						text: this.name,
						font: '12px sans-serif',
						showBackground: true,
						backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.8),
						backgroundPadding: new Cesium.Cartesian2(6, 4),
						outlineWidth: 1,
						verticalOrigin: Cesium.VerticalOrigin.TOP,
						horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
						pixelOffset: new Cesium.Cartesian2(10, -10),
						fillColor: Cesium.Color.WHITE,
						scale: 0.8
				  }
				: undefined,

			// 自定义属性
			customProperties: {
				orbitElements: this.orbitElements,
				orbitInfo: this.orbitCalculator.getOrbitInfo(),
				orbitCalculator: this.orbitCalculator
			}
		};

		return this.entity;
	}

	/**
	 * 创建描述信息
	 * @returns {string} HTML格式的描述信息
	 */
	_createDescription() {
		const orbitInfo = this.orbitCalculator.getOrbitInfo();

		return `
			<div style="font-family: Arial, sans-serif; font-size: 12px;">
				<h4 style="margin: 0 0 10px 0; color: #48b; border-bottom: 1px solid #ccc; padding-bottom: 5px;">${this.name}</h4>
				<table style="width: 100%; border-collapse: collapse;">
					<tr><td style="padding: 2px 8px 2px 0; font-weight: bold;">轨道类型:</td><td style="padding: 2px 0;">${
						orbitInfo.orbitType
					}</td></tr>
					<tr><td style="padding: 2px 8px 2px 0; font-weight: bold;">半长轴:</td><td style="padding: 2px 0;">${orbitInfo.semiMajorAxis.toFixed(
						2
					)} km</td></tr>
					<tr><td style="padding: 2px 8px 2px 0; font-weight: bold;">偏心率:</td><td style="padding: 2px 0;">${orbitInfo.eccentricity.toFixed(
						4
					)}</td></tr>
					<tr><td style="padding: 2px 8px 2px 0; font-weight: bold;">轨道倾角:</td><td style="padding: 2px 0;">${orbitInfo.inclination.toFixed(
						2
					)}°</td></tr>
					<tr><td style="padding: 2px 8px 2px 0; font-weight: bold;">升交点赤经:</td><td style="padding: 2px 0;">${orbitInfo.raan.toFixed(
						2
					)}°</td></tr>
					<tr><td style="padding: 2px 8px 2px 0; font-weight: bold;">近地点幅角:</td><td style="padding: 2px 0;">${orbitInfo.argumentOfPerigee.toFixed(
						2
					)}°</td></tr>
					<tr><td style="padding: 2px 8px 2px 0; font-weight: bold;">轨道周期:</td><td style="padding: 2px 0;">${(
						orbitInfo.orbitalPeriod / 3600
					).toFixed(2)} 小时</td></tr>
					<tr><td style="padding: 2px 8px 2px 0; font-weight: bold;">近地点高度:</td><td style="padding: 2px 0;">${orbitInfo.perigeeAltitude.toFixed(
						2
					)} km</td></tr>
					<tr><td style="padding: 2px 8px 2px 0; font-weight: bold;">远地点高度:</td><td style="padding: 2px 0;">${orbitInfo.apogeeAltitude.toFixed(
						2
					)} km</td></tr>
				</table>
			</div>
		`;
	}

	/**
	 * 更新轨道参数
	 * @param {Object} newElements - 新的轨道六根数
	 * @param {Object} options - 更新选项
	 */
	updateOrbitElements(newElements, options = {}) {
		// 更新轨道计算器
		this.orbitCalculator.updateOrbitElements(newElements, options.epoch);

		// 更新本地轨道参数
		this.orbitElements = { ...this.orbitElements, ...newElements };

		// 如果实体已创建，需要重新创建位置属性
		if (this.entity && options.updateEntity !== false) {
			this.entity.position = this._createPositionProperty();
			this.entity.description = this._createDescription();
			this.entity.customProperties.orbitElements = this.orbitElements;
			this.entity.customProperties.orbitInfo = this.orbitCalculator.getOrbitInfo();
		}
	}

	/**
	 * 更新显示选项
	 * @param {Object} options - 显示选项
	 */
	updateDisplayOptions(options) {
		if (!this.entity) return;

		if (options.showPath !== undefined) {
			this.entity.path.show = options.showPath;
			this.showPath = options.showPath;
		}

		if (options.showLabel !== undefined) {
			if (options.showLabel && !this.entity.label) {
				// 创建标签
				this.entity.label = {
					text: this.name,
					font: '12px sans-serif',
					showBackground: true,
					backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.8),
					backgroundPadding: new Cesium.Cartesian2(6, 4),
					outlineWidth: 1,
					verticalOrigin: Cesium.VerticalOrigin.TOP,
					horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
					pixelOffset: new Cesium.Cartesian2(10, -10),
					fillColor: Cesium.Color.WHITE,
					scale: 0.8
				};
			} else if (!options.showLabel) {
				this.entity.label = undefined;
			}
			this.showLabel = options.showLabel;
		}

		if (options.color) {
			this.color = options.color;
			this.entity.point.color = options.color;
			this.entity.path.material = options.color;
		}

		if (options.pointSize) {
			this.pointSize = options.pointSize;
			this.entity.point.pixelSize = options.pointSize;
		}

		if (options.pathWidth) {
			this.pathWidth = options.pathWidth;
			this.entity.path.width = options.pathWidth;
		}
	}

	/**
	 * 获取指定时间的卫星状态
	 * @param {number} time - 时间戳
	 * @returns {Object} 卫星状态信息
	 */
	getSatelliteState(time) {
		return this.orbitCalculator.calculateStateVector(time);
	}

	/**
	 * 获取轨道信息
	 * @returns {Object} 轨道信息
	 */
	getOrbitInfo() {
		return this.orbitCalculator.getOrbitInfo();
	}

	/**
	 * 获取轨道轨迹
	 * @param {number} startTime - 开始时间
	 * @param {number} duration - 持续时间 (秒)
	 * @param {number} stepSize - 步长 (秒)
	 * @returns {Array} 轨道轨迹点数组
	 */
	getOrbitTrajectory(startTime, duration, stepSize = 60) {
		return this.orbitCalculator.generateOrbitTrajectory(startTime, duration, stepSize);
	}

	/**
	 * 销毁实体
	 */
	destroy() {
		this.entity = null;
		this.orbitCalculator = null;
	}

	/**
	 * 从轨道六根数创建卫星实体的静态方法
	 * @param {string} name - 卫星名称
	 * @param {Object} orbitElements - 轨道六根数
	 * @param {Object} options - 可选参数
	 * @returns {CustomSatelliteEntity} 自定义卫星实体实例
	 */
	static fromOrbitElements(name, orbitElements, options = {}) {
		return new CustomSatelliteEntity({
			name: name,
			orbitElements: orbitElements,
			options: options
		});
	}

	/**
	 * 从预设模板创建卫星实体的静态方法
	 * @param {string} name - 卫星名称
	 * @param {string} templateKey - 模板键值
	 * @param {Object} options - 可选参数
	 * @returns {CustomSatelliteEntity} 自定义卫星实体实例
	 */
	static fromTemplate(name, templateKey, options = {}) {
		const templates = {
			'leo-sun-sync': {
				semiMajorAxis: 7178,
				eccentricity: 0.001,
				inclination: 98.2,
				raan: 0.0,
				argumentOfPerigee: 0.0,
				meanAnomaly: 0.0
			},
			'leo-iss': {
				semiMajorAxis: 6793,
				eccentricity: 0.0003,
				inclination: 51.6,
				raan: 0.0,
				argumentOfPerigee: 0.0,
				meanAnomaly: 0.0
			},
			'meo-gps': {
				semiMajorAxis: 26560,
				eccentricity: 0.02,
				inclination: 55.0,
				raan: 0.0,
				argumentOfPerigee: 0.0,
				meanAnomaly: 0.0
			},
			'geo-stationary': {
				semiMajorAxis: 42164,
				eccentricity: 0.0,
				inclination: 0.0,
				raan: 0.0,
				argumentOfPerigee: 0.0,
				meanAnomaly: 0.0
			},
			'heo-molniya': {
				semiMajorAxis: 26600,
				eccentricity: 0.74,
				inclination: 63.4,
				raan: 0.0,
				argumentOfPerigee: 270.0,
				meanAnomaly: 0.0
			}
		};

		const template = templates[templateKey];
		if (!template) {
			throw new Error(`未知的轨道模板: ${templateKey}`);
		}

		return new CustomSatelliteEntity({
			name: name,
			orbitElements: template,
			options: options
		});
	}
}

export default CustomSatelliteEntity;
